Skip to content

Hms standalone rest server with Spring Boot#6327

Merged
deniskuzZ merged 3 commits intoapache:masterfrom
difin:hms-standalone-rest-server-with-spring-boot
Mar 13, 2026
Merged

Hms standalone rest server with Spring Boot#6327
deniskuzZ merged 3 commits intoapache:masterfrom
difin:hms-standalone-rest-server-with-spring-boot

Conversation

@difin
Copy link
Copy Markdown
Contributor

@difin difin commented Feb 19, 2026

What changes were proposed in this pull request?

The Standalone REST Catalog Server is reimplemented to use Spring Boot instead of plain Java:

  • Server framework – Uses Spring Boot with an embedded Jetty server instead of raw servlet wiring.
  • Health checks – Adds Actuator liveness and readiness probes; readiness verifies HMS connectivity via Thrift.
  • Observability – Exposes Prometheus metrics for Kubernetes HPA and monitoring.
  • Configuration – Keeps port and other settings in MetastoreConf but bridges them into Spring (e.g., via system properties) so Spring Boot uses the configured port.
  • Graceful shutdown – Uses Spring Boot’s shutdown handling with a configurable timeout.
    Standalone packaging – Adds a spring-boot-maven-plugin “exec” JAR for running the server as a standalone process.

Why are the changes needed?

Spring Boot improves how the Standalone REST Catalog Server is run and operated:

  • Kubernetes support – Liveness and readiness probes (/actuator/health/*) let Kubernetes reliably route traffic and restart unhealthy pods. Readiness includes an actual HMS connectivity check instead of a simple config check.
  • Observability – Prometheus metrics enable HPA, dashboards, and alerting, which is standard for production deployments.
  • Operational behavior – Graceful shutdown and a well-defined lifecycle reduce the chance of dropped requests during restarts.
  • Maintainability – Spring Boot replaces custom servlet wiring and configuration, and aligns with common patterns for cloud-native Java services.

Does this PR introduce any user-facing change?

If the standalone REST Catalog server is deployed in Kubernetes:

  • Liveness/readiness probes – Configure HTTP probes to use the new actuator endpoints:
    -- Liveness: httpGet: /actuator/health/liveness
    -- Readiness: httpGet: /actuator/health/readiness
  • Metrics/HPA – Prometheus scraping or custom metrics use /actuator/prometheus.

How was this patch tested?

Integration tests in TestStandaloneRESTCatalogServer and TestStandaloneRESTCatalogServerJwtAuth run the Spring Boot standalone HMS REST catalog server and verify liveness/readiness probes, Prometheus metrics, REST catalog operations, and JWT auth with Keycloak (Testcontainers).

@deniskuzZ
Copy link
Copy Markdown
Member

	Suppressed: java.lang.NullPointerException: Cannot invoke "org.keycloak.admin.client.Keycloak.close()" because "this.keycloak" is null
		at org.apache.iceberg.rest.extension.OAuth2AuthorizationServer.stop(OAuth2AuthorizationServer.java:181)
		at org.apache.iceberg.rest.extension.HiveRESTCatalogServerExtension.afterAll(HiveRESTCatalogServerExtension.java:124)
		... 1 more
Caused by: java.lang.ClassNotFoundException: jakarta.annotation.Priority

LOG.info("=== Test: Health Check ===");
String healthUrl = "http://localhost:" + restCatalogServer.getPort() + "/health";
public void testPrometheusMetrics() throws Exception {
Copy link
Copy Markdown
Member

@deniskuzZ deniskuzZ Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we use spring actuator? nice :)

@deniskuzZ
Copy link
Copy Markdown
Member

deniskuzZ commented Feb 20, 2026

to support OAuth / JWT Authentication don't we need SecurityConfig?

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.oauth2ResourceServer()
            .jwt(); // validate JWT tokens
    }
}

cc @okumin

Comment thread standalone-metastore/metastore-rest-catalog/pom.xml Outdated
Comment thread itests/qtest-iceberg/pom.xml Outdated
Comment thread standalone-metastore/metastore-rest-catalog/pom.xml Outdated
Comment thread standalone-metastore/metastore-rest-catalog/pom.xml Outdated
Comment thread standalone-metastore/metastore-rest-catalog/pom.xml
Comment thread standalone-metastore/metastore-rest-catalog/pom.xml Outdated
Comment thread standalone-metastore/metastore-rest-catalog/pom.xml
System.setProperty(ConfVars.CATALOG_SERVLET_PORT.getVarname(), String.valueOf(port));
}

StandaloneRESTCatalogServer server = new StandaloneRESTCatalogServer(conf);
Copy link
Copy Markdown
Member

@deniskuzZ deniskuzZ Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring Boot should manage the lifecycle of your application class. Typically you don't manually instantiate your @SpringBootApplication class. see above snippet

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Member

@deniskuzZ deniskuzZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added few comments, rest LGTM

Copy link
Copy Markdown
Member

@deniskuzZ deniskuzZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1

@sonarqubecloud
Copy link
Copy Markdown

@deniskuzZ deniskuzZ merged commit fddce4e into apache:master Mar 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants